<?php

/*

CREATE TABLE `wpff_cache` (
  `id` bigint(20) NOT NULL auto_increment,
  `hash` varchar(32) NOT NULL default '',
  `tstamp` timestamp(14) NOT NULL,
  `content` text NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `hash` (`hash`),
  KEY `tstamp` (`tstamp`)
) type=InnoDB;

*/

class Cache {
    
    /*
    
    What we do not cache:
    
    - any page served to a user with one of our cookies (or one of WP's cookies)
    
    - any page with an HTTP method != GET
    
    - any page with a REQUEST_URI containing an unescaped '?'

    */
    
    var $_db;
    var $_context;
    
    // configuration
    var $validity = 3600;       // seconds
    var $gc_probability = 25;   // one in n+1 chances of doing garbage collection
    
    var $active = true;    // is this cache active for the current context?
    
    // set by constructor
    var $_table;    // name of the DB table to use
    var $_valid;    // earliest valid timestamp for a cache item
    var $_lastmod;  // timestamp of last modification for the current context
    
    var $id;        // same as _id, can be used by plugins etc.
    var $_id;       // id of the cache item for the current context
    
    function Cache(&$frontend, $validity=3600, $gc_probability=25) {
        
        $this->_db =& $frontend->db;
        $this->_context =& $frontend->context;
        
        $this->validity = $validity;
        $this->gc_probability = $gc_probability;
        
        $this->_table = $frontend->tables_prefix . '_cache';
        $this->_valid = date('Y-m-d H:i:s', (time() - $this->validity));
        
        $this->id = md5($_SERVER['REQUEST_URI']);
        
        if ($_SERVER['REQUEST_METHOD'] != 'GET' || strpos($_SERVER['REQUEST_URI'], '?') !== false) {
            $this->active = false;
            return;
        }
        
        $wpcookie = 'wordpressuser_' . md5($frontend->options['wp_url']);
        
        foreach (array_keys($_COOKIE) as $k) {
            if ($k == 'lp_identity' || $k == $wpcookie) {
                $this->active = false;
                return;
            }
        }
        
        $this->_id = $this->id;
        
        // check the last modified date for the context
        
        $consider_comments = false;
        
        if (empty($this->_context['reqtype']))
            $consider_comments = true;  // any context where we don't show comments?
        
        $lastmod = $frontend->getLastModified($consider_comments);
        
        // try to respond to a conditional request
        $frontend->doConditionalGet($lastmod);
        
        $this->_lastmod = date('Y-m-d H:i:s', $lastmod);
        
        $r = rand(0, $this->gc_probability);
        
        if ($r == 0)
            $this->garbageCollect();

    }
    
    function getCache($id=null) {
        
        $id = (is_null($id) ? $this->_id : $id);
        
        if (is_null($id))
            return;
        
        $db =& $this->_db;
       
        $q = "select content from " . $this->_table . " where " .
            " hash='" . $this->_id . "' " .
            " and tstamp >= '" . $this->_valid . "' " .
            " and tstamp > '" . $this->_lastmod . "' " .
            " order by tstamp desc limit 1";

        $db->query($q);        
        
        if ($db->count == 0)
            return;
        
        return stripslashes($db->get('content')) . '<!-- served by LightPress DB Cache, last modified ' . $this->_lastmod . ' -->';
        
    }
    
    function setCache(&$content, $id=null) {
        $id = (is_null($id) ? $this->_id : $id);
        
        if (is_null($id))
            return;
        
        $this->_db->query(
            "insert into " . $this->_table . " VALUES (" .
            "NULL, " .
            "'" . $this->_id . "', " .
            "now(), " .
            "'" . addslashes($content) . "')");
    }
    
    function garbageCollect() {
        $this->_db->query("delete from " . $this->_table . " where tstamp < '" . $this->_valid . "'");
    }
    
}

?>
